home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Misc / ClipNotes.1.0 / Source / CNAppManager.m < prev    next >
Text File  |  1995-06-12  |  11KB  |  482 lines

  1. /* CEAppManager.m                 
  2.  *
  3.  * This is the basic controller of the App. It manages all big abstraction
  4.  * tasks for the panels, documents and connections to the outside.
  5.  *
  6.  * For interface-info see the header file. The comments in this file mostly
  7.  * cover only the real implementation details.
  8.  *
  9.  * Written by:         Thomas Engel
  10.  * Created:            23.10.1993 (Copyleft)
  11.  * Last modified:     07.05.1994
  12.  */
  13.  
  14. #import "CNAppManager.h"
  15. #import "Text_more.h"
  16. #import "Application_ext.h"
  17. #import <misckit/MiscString.h>
  18. #import <misckit/MiscTime.h>
  19. #import <misckit/MiscAppDefaults.h>
  20. #import <misckit/MiscAppExtensions.h>
  21.  
  22.  
  23. @implementation CNAppManager
  24.  
  25. - appWillInit:sender
  26. {
  27.     // This is the init part we need to pass before we get the messages that
  28.     // we have to open some files.
  29.     // To be able to init a class we need the have the Preferences,
  30.  
  31.     // preferences = [CNPreferencesManager new];
  32.  
  33.     tempPb = [Pasteboard newName:"CNTempPb"];
  34.     _notesLoaded = NO;
  35.     newPastes = 0;
  36.     [newPasteCountField setIntValue:newPastes];
  37.  
  38.     [notesWindow setFrameAutosaveName:"NotesWindow"];
  39.     _firstActivation = YES;
  40.  
  41.     [self openDefaults];
  42.     return self;
  43. }
  44.  
  45. - appDidInit:sender
  46. {
  47.     // This is some kind of late init. These object are need for working but
  48.     // not for reading the classes or having a class initialized.
  49.  
  50.  
  51.     [[NXApp appListener] setServicesDelegate:self];    
  52.     // Opening with nil won't cause the window to open if it should not..
  53.  
  54.     [self open:nil];
  55.     [notesWindow setMiniwindowImage:[NXImage findImageNamed:"NoteIcon"]];
  56.     return self;
  57. }
  58.  
  59. - (int)app:sender openFile:(const char *)path type:(const char *)type
  60. {
  61.     // This method is performed whenever a user opens a document from the
  62.     // Workspace Manager.
  63.     // We use our default file open method with some default params.
  64.     
  65.     return NO;
  66. }
  67.  
  68. - (BOOL)appAcceptsAnotherFile:sender
  69. {
  70.     // Inform the workspace that we can open multiple files.
  71.     return NO;
  72. }
  73.  
  74. - appDidBecomeActive:sender
  75. {
  76.     if( _firstActivation )
  77.     {        
  78.         _firstActivation = NO;
  79.         if( [NXApp didAutolaunch] )
  80.         {
  81.             [NXApp hide:self];
  82.             return self;
  83.         }
  84.     }
  85.     [notesWindow makeKeyAndOrderFront:self];
  86.     return self;
  87. }
  88.  
  89. - appWillTerminate:sender
  90. {
  91.     // Now lets see what we have...ask every window what is going on.
  92.  
  93.     BOOL    ready;
  94.     int    result;
  95.  
  96.     if( !_isEscaping )
  97.     {
  98.         [self save:self];
  99.         [self saveDefaults];    
  100.     }
  101.     else
  102.     {
  103.         ready = NO;
  104.         while( !ready )
  105.         {
  106.             result = NXRunAlertPanel( "Quit", "There are usaved notes.", 
  107.                                 "Review Notes", "Quit Anyway", "Cancel" );
  108.  
  109.             if( result == NX_ALERTOTHER )
  110.                 return nil;
  111.     
  112.             ready = YES;
  113.  
  114.             if( result == NX_ALERTDEFAULT )
  115.                 [notesWindow makeKeyAndOrderFront:self];
  116.         }
  117.     }
  118.  
  119.     return self;
  120. }
  121.  
  122. - app:sender powerOffIn:(int)ms andSave:(int)aFlag
  123. {    
  124.     // Now we might not be on the save side here !!
  125.     // There is no guarateen to write the data down fast enough.
  126.     // BUG: We should extend power off time here but seems like it is working.
  127.  
  128.     [self save:self];
  129.     [self saveDefaults];
  130.     return self;
  131. }
  132.  
  133. - powerOff:(NXEvent *)theEvent
  134. {    
  135.     // Now we might not be on the save side here !!
  136.     // There is no guarateen to write the data down fast enough.
  137.     // We can't extend power off time here.
  138.  
  139.     [self save:self];
  140.     [self saveDefaults];
  141.     return self;
  142. }
  143.  
  144. - showInfo:sender
  145. {
  146.     return self;
  147. }
  148.  
  149. - showPreferences:sender
  150. {
  151.     return self;
  152. }
  153.  
  154. - preferences
  155. {
  156.     return self;
  157. }
  158.  
  159. - openDefaults
  160. {
  161.     id    aPath;
  162.  
  163.     // Well now this is a little rough....maybe we should search for the files
  164.     // inside the ~/.AppInfo or even *Library/ClassEditor sections..anyway.    
  165.     // Now the Text-object has a bug that prevendts us from usign the prede-
  166.     // dinfen Template that is inside the preferences NIB part.
  167.     // So we have to load it from the appp bundle.
  168.  
  169.     aPath = [MiscString newWithString:"~/Library/ClipNotes/NoteTemplate.rtfd"];
  170.     [aPath replaceTildeWithHome];
  171.     if( [aPath doesExistInFileSystem] )
  172.         [notesTemplateText openRTFDFrom:[aPath stringValue]];
  173.     
  174.     else
  175.     {
  176.         [aPath setStringValue:"/LocalLibrary/ClipNotes/NoteTemplate.rtfd"];
  177.         [aPath cat:"/NoteTemplate.rtfd"];
  178.         if( [aPath doesExistInFileSystem] )
  179.             [notesTemplateText openRTFDFrom:[aPath stringValue]];
  180.  
  181.         else
  182.         {
  183.             [aPath setStringValue:[NXApp appDirectory]];
  184.             [aPath cat:"/NoteTemplate.rtfd"];
  185.             if( [aPath doesExistInFileSystem] )
  186.                 [notesTemplateText openRTFDFrom:[aPath stringValue]];
  187.         }
  188.     }
  189.     [aPath free];
  190.  
  191.     [notesWindow setFrameUsingName:[notesWindow frameAutosaveName]];
  192.  
  193.     // Now lets get the other..simpler defaults..
  194.     
  195.     if( [NXApp knowsDefaultValue:"EnableService"] )
  196.         [enableServicesSwitch setState:
  197.                             [NXApp defaultBoolValue:"EnableService"]];
  198.  
  199.     if( [NXApp knowsDefaultValue:"SaveWithBackup"] )
  200.         [saveWithBackupSwitch setState:
  201.                             [NXApp defaultBoolValue:"SaveWithBackup"]];
  202.  
  203.     if( [NXApp knowsDefaultValue:"ClipNotesPath"] )
  204.         [notesPathField setStringValue:[NXApp defaultValue:"ClipNotesPath"]];
  205.  
  206.     if( [NXApp knowsDefaultValue:"ReplaceSelection"] )
  207.         [replaceSelectionSwitch setState:
  208.                             [NXApp defaultBoolValue:"ReplaceSelection"]];
  209.  
  210.     if( [NXApp knowsDefaultValue:"InsertPosition"] )
  211.         [notesCreationModeSwitch selectCellWithTag:
  212.                             [NXApp defaultIntValue:"InsertPosition"]];
  213.  
  214.     if( [NXApp knowsDefaultValue:"Timeformat"] )
  215.         [timeFormatField setStringValue:[NXApp defaultValue:"Timeformat"]];
  216.  
  217.     if( [NXApp knowsDefaultValue:"Dateformat"] )
  218.         [dateFormatField setStringValue:[NXApp defaultValue:"Dateformat"]];
  219.  
  220.  
  221.     return self;
  222. }
  223.  
  224. - saveDefaults
  225. {
  226.     // Write down the defaults. 
  227.  
  228.     id    aPath;
  229.  
  230.     if( _templateChanged )
  231.     {
  232.         aPath = [MiscString newWithString:
  233.                                 "~/Library/ClipNotes/NoteTemplate.rtfd"];
  234.         
  235.         [aPath replaceTildeWithHome];
  236.         [notesTemplateText saveRTFDTo:[aPath stringValue]
  237.                           removeBackup:YES errorHandler:nil];
  238.         [aPath free];
  239.         _templateChanged = NO;
  240.     }
  241.  
  242.     // Now lets get the other..simpler defaults..
  243.     
  244.     [NXApp setDefault:"EnableService" toBool:[enableServicesSwitch state]];
  245.     [NXApp setDefault:"SaveWithBackup" toBool:[saveWithBackupSwitch state]];
  246.     [NXApp setDefault:"ClipNotesPath" to:[notesPathField stringValue]];
  247.     [NXApp setDefault:"ReplaceSelection" toBool:
  248.                                     [replaceSelectionSwitch state]];
  249.     [NXApp setDefault:"InsertPosition" toInt:
  250.                         [[notesCreationModeSwitch selectedCell] tag]];
  251.     [NXApp setDefault:"Timeformat" to:[timeFormatField stringValue]];
  252.     [NXApp setDefault:"Dateformat" to:[dateFormatField stringValue]];
  253.  
  254.     return self;
  255. }
  256.  
  257. - new:sender
  258. {
  259.     // All we do here is to put some default on the clip area.
  260.     // Well by default we wnat to see the notes in this case...
  261.  
  262.     [self open:self];
  263.     [tempNoteText selectAll:self];
  264.     [tempNoteText replaceSel:"My Note:"];
  265.     [self _pasteIt];
  266.     
  267.     return self;
  268. }
  269.  
  270. - open:sender
  271. {
  272.     id    path;
  273.     
  274.     // If the document was edited we should ask first !
  275.  
  276.     if( _notesLoaded == NO )
  277.     {
  278.         path = [[MiscString alloc] initDirectory:[notesPathField stringValue]
  279.                                 file:"ClipNotes.rtfd"];
  280.         [path replaceTildeWithHome];
  281.         [notesText openRTFDFrom:[path stringValue]];
  282.  
  283.         [path free];
  284.         _notesLoaded = YES;
  285.     }
  286.  
  287.     // If the notes are loaded we asume that this was triggered by the menu
  288.     // item and the user wants to see the entries. So just show the window.
  289.     // If the sender is nil we won't bring up the
  290.  
  291.     else if( _notesLoaded || sender != nil )
  292.         [notesWindow makeKeyAndOrderFront:self];
  293.  
  294.       return self;
  295. }
  296.  
  297. - save:sender
  298. {
  299.     id    path;
  300.     BOOL    removeBackup;
  301.  
  302.     if( [notesWindow isDocEdited] == NO ) return self;
  303.  
  304.     // Now lets see if we need a backup or not..
  305.  
  306.     removeBackup = NO;
  307.     if( [saveWithBackupSwitch state] == NO ) removeBackup = YES;
  308.  
  309.     path = [[MiscString alloc] initDirectory:[notesPathField stringValue]
  310.                             file:"ClipNotes.rtfd"];
  311.     [path replaceTildeWithHome];
  312.     [notesText saveRTFDTo:[path stringValue] removeBackup:removeBackup 
  313.             errorHandler:nil];
  314.  
  315.     [path free];
  316.  
  317.  
  318.     newPastes = 0;
  319.     [newPasteCountField setIntValue:newPastes];
  320.     [notesWindow setDocEdited:NO];
  321.  
  322.     // Well somehow the notes are loaded now...at least the stored don't
  323.     // differ from what we have.
  324.  
  325.     _notesLoaded = YES;
  326.  
  327.     return self;
  328. }
  329.  
  330. - revert:sender
  331. {
  332.     if( [notesWindow isDocEdited] == NO ) return [self open:self];
  333.  
  334.     // Oh...there really is something to revert...not only topping the
  335.     // windows.
  336.  
  337.     if( NXRunAlertPanel( "Revert", 
  338.                 "Do you want the revert changes to the saved ClipNotes?", 
  339.                 "Revert", "Cancel", NULL ) == NX_ALERTDEFAULT )
  340.     {
  341.         _notesLoaded = NO;
  342.         [self open:self];
  343.     }
  344.     return self;
  345. }
  346.  
  347. - print:sender
  348. {
  349.     [notesText printPSCode:sender];
  350.     return self;
  351. }
  352.  
  353. - escape:sender
  354. {
  355.     _isEscaping = YES;
  356.     [NXApp terminate:self];
  357.     return self;
  358. }
  359.  
  360. - copyNotesTemplate
  361. {
  362.     // All we do here is to copy the docu template to the pasteboard.
  363.     // Will corrupt the pasteboard !
  364.  
  365.     [notesTemplateText selectAll:self];
  366.     [notesTemplateText copyTo:tempPb];
  367.     [composeText selectAll:self];
  368.     [composeText pasteFrom:tempPb];
  369.     [notesTemplateText selectNull];
  370.  
  371.     return self;
  372. }
  373.  
  374. - pasteAsNote:sender
  375. {
  376.     // All we do here is to paste the current pasteboard contents into the
  377.     // temp area and trigger a notes pasting operation (_pasteIt )
  378.  
  379.     [tempNoteText selectAll:self];
  380.     [tempNoteText paste:self];
  381.     [self _pasteIt];
  382.     
  383.     return self;
  384. }
  385.  
  386. - _pasteIt
  387. {
  388.     // We will paste the text that is inside the tempArea.
  389.  
  390.     id    aTime;
  391.  
  392.     [self copyNotesTemplate];
  393.  
  394.     // Now lets update the stuff that is inside the compose area to
  395.     // match our needs.
  396.  
  397.     [composeText setSel:0 :0];
  398.     if( [composeText findText:"<App>" 
  399.                     ignoreCase:NO backwards:NO wrap:NO] )
  400.     {
  401.         if( [NXApp isActive] )
  402.             [composeText replaceSel:"Pasteboard"];
  403.         else    [composeText replaceSel:"SomeApp"];
  404.     }
  405.  
  406.     [composeText setSel:0 :0];
  407.     if( [composeText findText:"<Time>" 
  408.                     ignoreCase:NO backwards:NO wrap:NO] )
  409.     {
  410.         aTime = [[MiscTime alloc] initWithCurrentTime];
  411.         [composeText replaceSel:[aTime format:[timeFormatField stringValue]]];
  412.         [aTime free];
  413.     }
  414.     
  415.     [composeText setSel:0 :0];
  416.     if( [composeText findText:"<Date>" 
  417.                     ignoreCase:NO backwards:NO wrap:NO] )
  418.     {
  419.         aTime = [[MiscTime alloc] initWithCurrentTime];
  420.         [composeText replaceSel:[aTime format:[dateFormatField stringValue]]];
  421.         [aTime free];
  422.     }
  423.  
  424.     [tempNoteText selectAll:self];
  425.     [tempNoteText copyTo:tempPb];
  426.     [composeText setSel:0 :0];
  427.     if( [composeText findText:"<Note>" 
  428.                     ignoreCase:NO backwards:NO wrap:NO] )
  429.         [composeText pasteFrom:tempPb];
  430.  
  431.     [composeText selectAll:self];
  432.     [composeText copyTo:tempPb];
  433.     
  434.     // Now depending on where we should paste the note we will set our 
  435.     // position.
  436.     
  437.     if( [replaceSelectionSwitch state] == NO ||
  438.         [notesText hasEmptySelection] )
  439.     {
  440.         if( [[notesCreationModeSwitch selectedCell] tag] == 1 )
  441.                 [notesText setSel:0 :0];
  442.         else        [notesText setSel:[notesText textLength]
  443.                                 :[notesText textLength]];
  444.     }
  445.     [notesText pasteFrom:tempPb];
  446.  
  447.     // In every case we will deselect it all afterwards. This way we can 
  448.     // prevent a replaceSelection setting to remove all our last clips. !
  449.  
  450.     [notesText setSel:0 :0];
  451.  
  452.     newPastes++;
  453.     [newPasteCountField setIntValue:newPastes];
  454.     [notesWindow setDocEdited:YES];
  455.  
  456.     return self;
  457. }
  458.  
  459. - note:(id)pb userData:(const char *)udata error:(char **)ermsg
  460. {
  461.     [tempNoteText selectAll:self];
  462.     [tempNoteText pasteFrom:pb];
  463.     [self _pasteIt];
  464.     return self;
  465. }
  466.  
  467. - textDidChange:sender
  468. {
  469.     if( sender == notesTemplateText ) _templateChanged = YES;
  470.  
  471.     else if( sender == notesText ) [notesWindow setDocEdited:YES];
  472.     return self;
  473. }
  474.  
  475. @end
  476.  
  477. /*
  478.  * History: 13.01.95 Bla.
  479.  *
  480.  *
  481.  * Bugs: No bugs and birds seen....
  482.  */